#include <QtNetwork/QtNetwork>
#include <QtNetwork/QTcpSocket>
#include "changepassworddataaccess.h"
#include "common/dynobjectfactory.h"
#include "common/jinstream.h"
#include "control/bankexception.h"

#define CHANGE_PASSWORD    0x07
#define BUF_SIZE    1024

ChangePasswordDataAccess::ChangePasswordDataAccess()
{
    data_ = new char[BUF_SIZE];
}

ChangePasswordDataAccess::~ChangePasswordDataAccess()
{
    delete []data_;
}

//数据进行请求发送
bool ChangePasswordDataAccess::requestData(QSharedPointer<QTcpSocket> &cliPipe,
                                           map<QString, QString> &rDataMap)
{
    jos_.Clear();
    quint16 cmd = CHANGE_PASSWORD;
    jos_ << cmd;
    // 预留两个字节包头len(包体+包尾长度)
    quint64 lengthPos = jos_.Length();
    jos_.Skip(2);
    /*
     *  账户ID（文本框）（提示：长度6位，数字）
        账户密码（文本框）（提示：长度6-8位）
        新密码（文本框）（提示：长度6-8位）
    */
    map<QString,QString>::const_iterator it;
    //帐号
    it = rDataMap.find("id");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute id can't be found!"));
        return false;
    }
    const char *pAccountId = it->second.toLocal8Bit();
    jos_.WriteBytes((quint8 *)pAccountId,it->second.length());
    // 帐号密码
    it = rDataMap.find("pass");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute pass can't be found!"));
        return false;
    }
    QString pass = it->second;
    encryPassword(pass,cmd);
    //新密码
    it = rDataMap.find("newPass");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute newPass can't be found!"));
        return false;
    }
    QString nPass = it->second;
    encryPassword(nPass,cmd);
    // 包头len字段
    quint64 tailPos = jos_.Length();
    jos_.Reposition(lengthPos);
    jos_ << (quint16)(tailPos + 8 - sizeof(RequestHead));
    // 包尾
    jos_.Reposition(tailPos);
    generatePackTailMd5(cmd);
    cliPipe->write(jos_.Data(), jos_.Length());
    if(!cliPipe->waitForBytesWritten(3000)) {
        throw BankException(cliPipe->errorString().toLocal8Bit());
    }
    return true;
}

//对数据进行响应
bool ChangePasswordDataAccess::responseData(QSharedPointer<QTcpSocket> &cliPipe,
                                                map<QString, QString> &rDataMap)
{
    memset(data_,0,BUF_SIZE);
    if(!cliPipe->waitForReadyRead(3000)) {
        throw BankException(cliPipe->errorString().toLocal8Bit());
    }
    dataLen_ = cliPipe->read(data_,BUF_SIZE);
    //这里应该执行接收包的包验证
    if(!checkData()) {
        throw BankException("data check sum error!");
    }
    JInStream jis((const char*)data_, dataLen_);
    // 跳过cmd、len
    jis.Skip(4);
    uint16 cnt;
    uint16 seq;
    int16 error_code;
    jis >> cnt >> seq >> error_code;
    //这些冗余代码还可以通过重构来进一步的优化
    char error_msg[31];
    memset(error_msg,0,sizeof(error_msg));
    jis.ReadBytes(error_msg, 30);
    if(0 != error_code) {
        rDataMap.insert(make_pair("errorMsg",
                                error_msg));
        return false;
    }
    return true;
}

REGISTER_CLASS(ChangePasswordDataAccess);
